package com.opdar.athena.web.service;

import com.opdar.athena.base.Constants;
import com.opdar.athena.base.RedisSessionManager;
import com.opdar.athena.entities.ErrorResult;
import com.opdar.athena.entities.MessageEntity;
import com.opdar.athena.mapper.MessageMapper;
import com.opdar.athena.web.senders.ISender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.util.concurrent.ListenableFuture;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import static com.opdar.athena.base.Constants.ErrorCode.MESSAGE_IS_NOT_EXIST;

/**
 * Created by shiju on 2017/7/2.
 */
@Service
public class MessageService {
    @Autowired
    MessageMapper messageMapper;
    @Autowired
    private ISender sender;
    @Autowired
    UserService userService;
    @Autowired
    private RedisSessionManager sessionManager;


    /**
     //type: 1.整体迁移 2.随机迁移 3.单体迁移
     * 迁移用户至其他服务器
     */
    public void migrate(String source,String destination,String token,long num,int type){
        //迁移状态
        int status = 1;
        ByteArrayOutputStream byteArrayOutputStream;
        DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream = new ByteArrayOutputStream());
        try {
            String id = UUID.randomUUID().toString();
            dataOutputStream.writeUTF(id);
            dataOutputStream.writeUTF(source);
            dataOutputStream.writeUTF(destination);
            dataOutputStream.writeInt(type);
            dataOutputStream.writeInt(status);
            dataOutputStream.writeLong(num);
            dataOutputStream.writeUTF(token);
            sender.send("MIGRATE", source, byteArrayOutputStream.toByteArray());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Transactional(rollbackFor = Throwable.class)
    public Object send(String content, Integer type, String fakeId, String sender, String reciver){
        if(!userService.exist(reciver)){
            return new ErrorResult(Constants.ErrorCode.RECIVER_IS_NOT_EXIST);
        }
        MessageEntity messageEntity = new MessageEntity();
        messageEntity.setId(UUID.randomUUID().toString());
        messageEntity.setContent(content);
        messageEntity.setFakeId(fakeId);
        messageEntity.setType(type);
        messageEntity.setOld(0);
        messageEntity.setSender(sender);
        messageEntity.setReciver(reciver);
        messageEntity.setStat(Constants.Message.READY);
        messageEntity.setCreateTime(new Timestamp(System.currentTimeMillis()));
        messageEntity.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        int ret = messageMapper.insert(messageEntity);
        if(ret > 0){
            this.sender.send(reciver,messageEntity.getId().getBytes());
        }
        return messageEntity;
    }

    @Transactional(rollbackFor = Throwable.class)
    public Object find(String sender, String reciver, Timestamp ltTime, Timestamp gtTime) {
        MessageEntity message = new MessageEntity();
        if(StringUtils.isEmpty(reciver))return new ArrayList();
        if(StringUtils.isEmpty(ltTime))ltTime = new Timestamp(System.currentTimeMillis());
        message.setReciver(reciver);
        message.setSender(sender);
        messageMapper.updateReadStat(message,ltTime,gtTime);
        return messageMapper.selectList2(message,ltTime,gtTime);
    }

    public Object notifyMsg(String messageId) {
        MessageEntity message = new MessageEntity();
        message.setId(messageId);
        message = messageMapper.selectOne(message);
        if(message != null){
            this.sender.send(message.getSender(),message.getId().getBytes());
            return new ErrorResult();
        }
        return new ErrorResult(MESSAGE_IS_NOT_EXIST);
    }

    public Object findReadCount(String sender, String reciver) {
        MessageEntity message = new MessageEntity();
        message.setSender(sender);
        message.setReciver(reciver);
        return messageMapper.selectUnReadCount(message);
    }

    public Object updateReadCount(String messageId) {
        MessageEntity message = new MessageEntity();
        message.setId(messageId);
        return messageMapper.updateReadStat(message,null,null);
    }
}
